#include <stdio.h>

#include "Temp.h"

//#define _test_
#ifdef _test_
int main(void){
	setlocale(LC_ALL, "");
	struct String * str = initString();
	int i;
	for(i = 0; i < 1000; i++){

		strInsert(lenOfStr(str), L'我', str);
		printf("lenOfStr: %d\n", lenOfStr(str));
	}
	
	return 0;
}
#endif

ContentList* initContent(void){
	ContentList* cl = malloc(sizeof(ContentList));
	cl -> strs = (struct String*) malloc(sizeof(struct String) * 30);
	cl -> totle = 0;
	cl -> max = 30;
	return cl;
}

void pushContentByCharArray(wchar_t * ws, ContentList * cl, int memsize){
	struct String* str = (struct String*) malloc(sizeof(struct String));
	str -> str = ws;
	str -> memsize = memsize;
	pushContent(str, cl);
}

void pushContent(struct String* content, ContentList * cl){
	if(cl -> totle >= cl -> max){
		int old_size = cl -> max;
		int new_size = old_size * 2;
		struct String** new_pointer = (struct String**) malloc(sizeof(wchar_t*) * new_size);
		memcpy(new_pointer, cl -> strs, sizeof(struct String*) * old_size);
		free(cl -> strs);
		cl -> strs = new_pointer;
		cl -> max = new_size;
	}
	cl -> strs[cl -> totle] = content;
	cl -> totle ++;
}

struct String* getContent(int i, ContentList * cl){
	if(cl -> totle - 1 < i || i < 0){
		return NULL;
	}else{
		return cl -> strs[i];
	}
}

int getContentSize(int i, ContentList * cl){
	if(cl -> totle - 1 < i || i < 0){
		return -1;
	}else{
		return cl -> strs[i] -> memsize;
	}
}

int deleteValue(int i, ContentList * cl){
	int index;
	if(cl -> totle - 1 < i || i < 0)
		return 0;
	else{
		destoryStr(&(cl -> strs[i]));
		for(index = i + 1; index < cl -> totle; index ++){
			cl -> strs[index - 1] = cl -> strs[index];
		}
		cl -> totle --;
		return 1;
	}
}

void deleteContent(ContentList * cl){
	int i;
	if(cl -> totle != 0){
		for(i = 0; i < cl -> totle; i++){
			destoryStr(&(cl -> strs[i]));
		}
		free(cl -> strs);
		cl -> max = 0;
		cl -> totle = 0;
	}
}

void insertContent(struct String* insert_str, int index, ContentList * cl){
	int i;
	if(cl -> totle >= cl -> max){
		int old_size = cl -> max;
		int new_size = old_size * 2;
		struct String** new_pointer = (struct String**) malloc(sizeof(struct String*) * new_size);
		memcpy(new_pointer, cl -> strs, sizeof(struct String*) * old_size);
		free(cl -> strs);
		cl -> max = new_size;
		cl -> strs = new_pointer;
	}
	//XIAOC, CAN YOU HEAR ME? CAN YOU SEE ME?
	//I WANT TO HAVE A COMPANY NAMED BY YOUR NAME.
	//I LOVE YOU, BUT AT THAT TIME I DON'T KNOW HOW TO EXPRESS.
	//SORRY TO MAKE YOU SAD. SORRY TO MAKE YOU DISLIKE ME.
	//MAYBE NO ONE CAN SEE THIS.
	//MAYBE I'LL BE SUCCESS, BUT IT STILL MAKE ME SAD BECAUSE I CAN'T GO WITH YOU TOGETHER...
	for(i = cl -> totle - 1; i >= index; i--){
		cl -> strs[i + 1] = cl -> strs[i];
	}
	cl -> strs[index] = insert_str;
}

int lenOfContent(ContentList* cl){
	return cl -> totle;
}


void strInsert(int index, wchar_t wc, struct String* str){
	int memsize = str -> memsize;
	wchar_t * tmp_pointer;
	int i;
	int strlen = wcslen(str -> str);
	if(index < 0 || index > strlen)
		return;
	if(strlen + 1 >= memsize){
		memsize *= 2;
		tmp_pointer = str -> str;
		str -> str = (wchar_t*) malloc(sizeof(wchar_t) * memsize);
		str -> memsize = memsize;
		memcpy(str -> str, tmp_pointer, (memsize / 2) * sizeof(wchar_t));
		free(tmp_pointer);
	}
	for(i = strlen; i >= index; i--){
		str -> str[i + 1] = str -> str[i];
	}
	str -> str[index] = wc;
}


void strDelete(int index, struct String* str){
	int i;
	int strlen = wcslen(str -> str);
	
	if(index < 0 || index >= strlen)
		return;
	
	for(i = index; i <= strlen; i++){
		str -> str[i] = str -> str[i + 1];
	}
}

void destoryStr(struct String* str){
	free(str -> str);
}

int lenOfStr(struct String * str){
	return wcslen(str -> str);
}

int spaceOfStr(struct String * str, int index){
	wchar_t * str_pointer = str -> str;
	int space_count = 0;
	int i;
	int len = lenOfStr(str);
	if(index > len || index <= 0) index = len;
	for(i = 0; i < index; i++){
		if(str_pointer[i] & 0xffffff00){
			space_count += 2;
		}else{
			space_count ++;
		}
	}
	return space_count;
}

int fromSpaceToIndex(struct String* str, int space){
	wchar_t * str_pointer = str -> str;
	int i;
	int len = lenOfStr(str);
	int nowSpace = 0;
	for(i = 0; i < len && nowSpace < space; i++){
		if(str_pointer[i] & 0xffffff00){
			nowSpace += 2;
		}else{
			nowSpace += 1;
		}
	}
	return i;
}

struct String* initString(void){
	struct String * string = (struct String*) malloc(sizeof(struct String));
	string -> str = (wchar_t*) malloc(sizeof(wchar_t) * 50);
	string -> memsize = 50;
	return string;
}

void strAppend(struct String* aim, struct String* bullet){
	int aimLen = lenOfStr(aim);
	int bulletLen = lenOfStr(bullet);
	int memsize = aim -> memsize;
	struct String* tmp_pointer;
	while(aimLen + bulletLen + 1 >= memsize){
		memsize *= 2;
		tmp_pointer = aim -> str;
		aim -> str = (wchar_t*) malloc(sizeof(wchar_t) * memsize);
		memcpy(aim -> str, tmp_pointer, (memsize / 2) * sizeof(wchar_t));
		free(tmp_pointer);
	}
	(*aim).memsize = memsize;
	memcpy(aim -> str + aimLen, bullet -> str, bulletLen * sizeof(wchar_t) + 1);
}
